package ontocompo.ui.screenmanagement;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class ScreenFlowPane extends JPanel implements ScreenConsumer, Observer {

	private ArrayList<Screen> availabledScreens;
	private ScreenFlowSelector screenFlowSelector;
	
	private Screen selectedScreen;
	
	private JPanel workingScreenPanel;
	private JPanel actionsScreenPanel;
	
	private JComboBox screenList;
	private JButton linkedScreenButton;
	private JList screenFlowDescription;
	private DefaultListModel screenFlowDescriptionData;
	private JButton addNextScreenButton;
	
	public ScreenFlowPane(ArrayList<Screen> screens, ScreenFlowSelector sfc) {
		super();
		
		this.availabledScreens = screens;
		this.screenFlowSelector = sfc;
		this.screenFlowSelector.addObserver(this);
		
		this.build();
	}
	
	private void build() {
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		
		ScreenPossibilities ep = new ScreenPossibilities(false, null, true, this);
		ep.setButtonMessage("select");
		ep.init();
		ep.updateScreensList(availabledScreens);
		add(ep);
		
		JPanel screenFlowPanel = new JPanel();
		screenFlowPanel.setLayout(new BoxLayout(screenFlowPanel, BoxLayout.X_AXIS));
		add(screenFlowPanel);
		
		workingScreenPanel = new JPanel();
		screenFlowPanel.add(workingScreenPanel);
		
		actionsScreenPanel = new JPanel();
		actionsScreenPanel.setLayout(new BoxLayout(actionsScreenPanel, BoxLayout.Y_AXIS));
		JPanel linkedScreenPanel = new JPanel();
		linkedScreenPanel.setLayout(new BoxLayout(linkedScreenPanel, BoxLayout.X_AXIS));
		screenList = new JComboBox(this.availabledScreens.toArray());
		this.screenList.setEnabled(false);
		linkedScreenPanel.add(screenList);
		linkedScreenButton = new JButton("Attached button to selected screen");
		linkedScreenButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				linkedScreenToButton();
			}
			
		});
		this.linkedScreenButton.setEnabled(false);
		linkedScreenPanel.add(linkedScreenButton);
		actionsScreenPanel.add(linkedScreenPanel);
		
		addNextScreenButton = new JButton("Add a 'Next Screen' button");
		addNextScreenButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				addNextScreenbutton();
			}
			
		});
		actionsScreenPanel.add(addNextScreenButton);
		
		screenFlowPanel.add(actionsScreenPanel);
		
		
		JPanel screenFlowInfoPanel = new JPanel();
		screenFlowInfoPanel.setLayout(new BoxLayout(screenFlowInfoPanel, BoxLayout.Y_AXIS));
		screenFlowInfoPanel.add(new JLabel("Screenflow links from selected screen"));
		screenFlowDescriptionData = new DefaultListModel();
		screenFlowDescription = new JList(screenFlowDescriptionData);
		JScrollPane listScroller = new JScrollPane(screenFlowDescription);
		listScroller.setPreferredSize(new Dimension(60, 40));
		//screenFlowDescription.setEnabled(false);
		screenFlowInfoPanel.add(listScroller);
		screenFlowPanel.add(screenFlowInfoPanel);
	}
	
	public void linkedScreenToButton() {
		this.selectedScreen.addToScreenFlow(this.screenFlowSelector.getSelectedButton(), (Screen) this.screenList.getSelectedItem());
		
		this.updateScreenFlowDescription();
		
		this.validate();
	}
	
	public void updateScreenFlowDescription() {
		
		screenFlowDescriptionData.removeAllElements();
		
		HashMap<JComponent, Screen> screenflow = this.selectedScreen.getScreenFlow();
		String[] data = new String[screenflow.size()];
		//int pos = 0;
		for(JComponent jc : screenflow.keySet()) {
			//data[pos++] = jc.getName() + " linked to screen '" + screenflow.get(jc).getName() + "'";
			screenFlowDescriptionData.addElement("" + jc + " linked to screen '" + screenflow.get(jc).getName() + "'");
		}
		
		this.screenFlowDescription = new JList(data);
	}
	
	@Override
	public void consume(Screen s) {
		// TODO Auto-generated method stub
		this.workingScreenPanel.removeAll();
		
		this.workingScreenPanel.add(s.getRootScreen());
		
		this.selectedScreen = s;
		
		this.updateScreenFlowDescription();
		
		this.update(null, "disable");
		
		if(this.selectedScreen.hasANextScreenButton()) {
			this.addNextScreenButton.setEnabled(false);
		} else {
			this.addNextScreenButton.setEnabled(true);
		}
		
		this.validate();
	}
	
	public void addNextScreenbutton() {
		JButton nextScreenButton = this.selectedScreen.addNextScreenButton();
		
		if(nextScreenButton != null) {
		
			nextScreenButton.addMouseListener(screenFlowSelector);
			
			this.screenFlowSelector.selectButton(nextScreenButton);
			
			this.addNextScreenButton.setEnabled(false);
			
			this.validate();
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		String state = (String) arg;
		
		if(state.equals("enable")) {
			this.screenList.setEnabled(true);
			this.linkedScreenButton.setEnabled(true);
		} else if(state.equals("disable")) {
			this.screenList.setEnabled(false);
			this.linkedScreenButton.setEnabled(false);
		}
	}

}
